#include "audio_sr.h"

static esp_afe_sr_iface_t *afe_handle = NULL;
static esp_afe_sr_data_t *afe_data = NULL;

my_sr_t my_sr;

void feed_task(void *args);  // 喂入数据
void fetck_task(void *args); // 检测唤醒
void audio_sr_init(void)
{
    srmodel_list_t *models = esp_srmodel_init("model");
    afe_config_t *afe_config =
        afe_config_init("M", models, AFE_TYPE_SR, AFE_MODE_LOW_COST);
    afe_config->aec_init = false;
    afe_config->se_init = false;
    afe_config->ns_init = false;
    afe_config->vad_init = true;
    afe_config->vad_mode = VAD_MODE_2;
    afe_config->vad_min_noise_ms = 500;
    afe_config->wakenet_init = true;        // 语音唤醒
    afe_config->wakenet_mode = DET_MODE_90; // 唤醒模式
    afe_handle = esp_afe_handle_from_config(afe_config);
    afe_data = afe_handle->create_from_config(afe_config);
}

void audio_sr_start(RingbufHandle_t ringBuf, void (*wake_up_callback)(void),
                    void (*vad_state_change_callback)(vad_state_t state))
{

    my_sr.sr_running = true;

    my_sr.is_wake = false;
    my_sr.wake_cb = wake_up_callback;
    my_sr.vad_state_change_cb = vad_state_change_callback;
    my_sr.ringBuf = ringBuf;
    xTaskCreateWithCaps(&feed_task, "feed_task", 4 * 1024, NULL, 5, NULL,
                        MALLOC_CAP_SPIRAM);
    xTaskCreateWithCaps(&fetck_task, "fetck_task", 4 * 1024, NULL, 5, NULL,
                        MALLOC_CAP_SPIRAM);
}

void feed_task(void *args)
{

    // 获取音频前端需要的音频块大小
    int feed_chunksize = afe_handle->get_feed_chunksize(afe_data);
    // 获取音频前端需要的音频通道数
    int feed_nch = afe_handle->get_feed_channel_num(afe_data);
    // 分配音频缓冲区：大小 = 块大小 × 通道数 × 每个样本大小(16位)
    int16_t *feed_buff =
        (int16_t *)malloc(feed_chunksize * feed_nch * sizeof(int16_t));

    while (my_sr.sr_running)
    {
        bsp_sound_read(feed_buff, feed_chunksize * sizeof(int16_t) * feed_nch);
        afe_handle->feed(afe_data, feed_buff);
    }

    free(feed_buff);
    vTaskDelete(NULL);
}

void fetck_task(void *args)
{

    while (my_sr.sr_running)
    {

        afe_fetch_result_t *result = afe_handle->fetch(afe_data);

        // 具体的识别后的音频数据
        int16_t *processed_audio = result->data;
        // 当前语音状态 说话或者静音
        vad_state_t vad_state = result->vad_state;
        // 当前唤醒状态 未检测到唤醒词 检测到唤醒词
        wakenet_state_t wakeup_state = result->wakeup_state;

        if (wakeup_state == WAKENET_DETECTED)
        {
            my_sr.is_wake = true;
            my_sr.last_vad_state = VAD_SILENCE; // 唤醒之后, vad设置为静音
            if (my_sr.wake_cb)
            {
                my_sr.wake_cb();
            }

            //   // 语音状态发生变化
            //   if (vad_state != my_sr.last_vad_state) {
            //     my_sr.last_vad_state = vad_state;
            //     if (my_sr.vad_state_change_cb) {
            //       my_sr.vad_state_change_cb(vad_state);
            //     }
            //   }
        }

        if (my_sr.is_wake)
        {
            // 语音状态发生变化
            if (vad_state != my_sr.last_vad_state)
            {
                my_sr.last_vad_state = vad_state;
                if (my_sr.vad_state_change_cb)
                {
                    my_sr.vad_state_change_cb(vad_state);
                }
            }
        }

        if (my_sr.is_wake && vad_state == VAD_SPEECH)
        {

            // if vad cache is exists, please attach the cache to the front of
            // processed_audio to avoid data loss
            if (result->vad_cache_size > 0)
            {
                int16_t *vad_cache = result->vad_cache;
                if (my_sr.ringBuf)
                {
                    xRingbufferSend(my_sr.ringBuf, vad_cache, result->vad_cache_size,
                                    0); // 将数据写入ringbuf
                }
            }

            if (my_sr.ringBuf)
            {
                xRingbufferSend(my_sr.ringBuf, processed_audio, result->data_size,
                                0); // 将数据写入ringbuf
            }
        }

    }
    vTaskDelete(NULL);
}
